package com.xp.flow.component;

import com.yomahub.liteflow.annotation.LiteflowComponent;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 延时等待组件
 * 支持指定时间的延时处理，可配置延时时长和时间单位
 * 
 * @author AI Assistant
 * @since 1.0.0
 */
@Slf4j
@LiteflowComponent("DELAY")
public class DelayComponent extends BaseFlowComponent {

    @Override
    public void process() {
        // 获取配置
        Integer delayTime = getConfigValue("delayTime", 5);
        String timeUnit = getConfigValue("timeUnit", "SECONDS");
        String description = getConfigValue("description", "延时等待");
        
        logExecution("开始执行延时等待: %s, 延时: %d %s", description, delayTime, timeUnit);
        
        // 获取输入数据
        Map<String, Object> inputData = getInputData();
        
        try {
            // 记录开始时间
            long startTime = System.currentTimeMillis();
            
            // 执行延时
            executeDelay(delayTime, timeUnit);
            
            // 计算实际延时时间
            long actualDelay = System.currentTimeMillis() - startTime;
            
            // 创建输出数据
            Map<String, Object> outputData = new HashMap<>(inputData);
            outputData.put("delayTime", delayTime);
            outputData.put("timeUnit", timeUnit);
            outputData.put("actualDelayMs", actualDelay);
            outputData.put("description", description);
            outputData.put("success", true);
            
            // 设置输出数据
            setOutputData(outputData);
            
            logExecution("延时等待完成，实际延时: %d毫秒", actualDelay);
            
        } catch (InterruptedException e) {
            logError("延时等待被中断", e);
            
            // 恢复中断状态
            Thread.currentThread().interrupt();
            
            // 创建错误输出
            Map<String, Object> errorData = new HashMap<>(inputData);
            errorData.put("error", true);
            errorData.put("errorMessage", "延时等待被中断");
            errorData.put("success", false);
            
            setOutputData(errorData);
            
        } catch (Exception e) {
            logError("延时等待执行失败", e);
            
            // 创建错误输出
            Map<String, Object> errorData = new HashMap<>(inputData);
            errorData.put("error", true);
            errorData.put("errorMessage", "延时等待执行失败: " + e.getMessage());
            errorData.put("success", false);
            
            setOutputData(errorData);
        }
    }
    
    /**
     * 执行延时等待
     * 
     * @param delayTime 延时时长
     * @param timeUnitStr 时间单位字符串
     * @throws InterruptedException 中断异常
     */
    private void executeDelay(int delayTime, String timeUnitStr) throws InterruptedException {
        if (delayTime <= 0) {
            logExecution("延时时间为0或负数，跳过延时");
            return;
        }
        
        // 解析时间单位
        TimeUnit unit = parseTimeUnit(timeUnitStr);
        
        // 执行延时
        logExecution("开始延时等待: %d %s", delayTime, timeUnitStr);
        unit.sleep(delayTime);
    }
    
    /**
     * 解析时间单位
     * 
     * @param timeUnitStr 时间单位字符串
     * @return TimeUnit枚举
     */
    private TimeUnit parseTimeUnit(String timeUnitStr) {
        if (timeUnitStr == null || timeUnitStr.trim().isEmpty()) {
            return TimeUnit.SECONDS;
        }
        
        String unit = timeUnitStr.trim().toUpperCase();
        
        switch (unit) {
            case "NANOSECONDS":
            case "NANOSECOND":
            case "NANOS":
            case "NS":
                return TimeUnit.NANOSECONDS;
                
            case "MICROSECONDS":
            case "MICROSECOND":
            case "MICROS":
            case "US":
                return TimeUnit.MICROSECONDS;
                
            case "MILLISECONDS":
            case "MILLISECOND":
            case "MILLIS":
            case "MS":
                return TimeUnit.MILLISECONDS;
                
            case "SECONDS":
            case "SECOND":
            case "SEC":
            case "S":
                return TimeUnit.SECONDS;
                
            case "MINUTES":
            case "MINUTE":
            case "MIN":
            case "M":
                return TimeUnit.MINUTES;
                
            case "HOURS":
            case "HOUR":
            case "H":
                return TimeUnit.HOURS;
                
            case "DAYS":
            case "DAY":
            case "D":
                return TimeUnit.DAYS;
                
            default:
                logExecution("未知的时间单位: %s，使用默认单位: SECONDS", timeUnitStr);
                return TimeUnit.SECONDS;
        }
    }
    
    /**
     * 将时间单位转换为毫秒
     * 
     * @param delayTime 延时时长
     * @param timeUnit 时间单位
     * @return 毫秒数
     */
    private long convertToMilliseconds(int delayTime, TimeUnit timeUnit) {
        return timeUnit.toMillis(delayTime);
    }
    
    /**
     * 格式化延时时间为可读字符串
     * 
     * @param delayTime 延时时长
     * @param timeUnit 时间单位
     * @return 格式化字符串
     */
    private String formatDelayTime(int delayTime, TimeUnit timeUnit) {
        return String.format("%d %s", delayTime, timeUnit.name().toLowerCase());
    }
}